#include <iostream>
#include "httplib.h"
#include "add_contacts.pb.h"

using std::cout;
using std::endl;
using std::cerr;
using namespace httplib;

class ContactsException
{
public:
    ContactsException(std::string str = "A problem") 
    :_message(str)
    {}

    std::string what() const { return _message;}
private:
    std::string _message;
};

void PrintContact(add_contacts::AddContactsReq& req)
{
    std::cout << "联系人姓名:" << req.name() << std::endl;
    std::cout << "联系人年龄:" << req.age() << std::endl;
    for (int i = 0; i < req.phones().size(); i++)
    {
        const add_contacts::AddContactsReq_Phone* phone = req.mutable_phones(i);
        std::cout << "联系人电话" << i + 1 << ":" << phone->number() 
            << "  (" << add_contacts::AddContactsReq_Phone_PhoneType_Name(phone->type()) << ")" << std::endl;
    }
}

static unsigned int random_char() {
    // ⽤于随机数引擎获得随机种⼦
    std::random_device rd;
    // mt19937是c++11新特性，它是⼀种随机数算法，⽤法与rand()函数类似，但是mt19937具有速度快，周期⻓的特点
    // 作⽤是⽣成伪随机数
    std::mt19937 gen(rd());
    // 随机⽣成⼀个整数i 范围[0, 255]
    std::uniform_int_distribution<> dis(0, 255);
    return dis(gen);
}

// ⽣成 UUID （通⽤唯⼀标识符）
static std::string generate_hex(const unsigned int len) {
    std::stringstream ss;
    // ⽣成 len 个16进制随机数，将其拼接⽽成
    for (auto i = 0; i < len; i++) 
    {
        const auto rc = random_char();
        std::stringstream hexstream;
        hexstream << std::hex << rc;
        auto hex = hexstream.str();
        ss << (hex.length() < 2 ? '0' + hex : hex);
    }
    return ss.str();
}

int main()
{
    cout << "----------服务启动-----------" << endl;

    Server server;
    server.Post("/contacts/add", [](const Request& req, Response& resp){
        cout << "接收到post请求!" << endl;
        // 反序列化req
        std::string resp_str = req.body;
        add_contacts::AddContactsReq request;
        add_contacts::AddContactsResp response;
        try{
            if (!request.ParseFromString(resp_str))
            {
                throw ContactsException("反序列化失败!");
            }

            
            // 新增联系人，持久化存储通讯录--->仅打印，有兴趣自行处理
            PrintContact(request);

            // 构建resp
            response.set_success(true);
            response.set_uid(generate_hex(10));

            // 序列化resp
            std::string resp_str;
            if (!response.SerializeToString(&resp_str))
            {
                throw ContactsException("AddContactsResp序列化失败！");
            }
            resp.status = 200;
            resp.body = resp_str;
            resp.set_header("Content-Type", "application/protobuf");
        }catch(const ContactsException& e)
        {
            resp.status = 500;
            response.set_success(false);
            response.set_error_desc(e.what());
            std::string resp_str;
            if (response.SerializeToString(&resp_str))
            {
                resp.body = resp_str;
                resp.set_header("Content-Type", "application/protobuf");
            }
            std::cout << "/contacts/add 发生异常,异常信息:" << e.what() << std::endl;
        }



    });

    server.listen("0.0.0.0", 8080);

    return 0;
}

// int main()
// {
//     cout << "----------服务启动-----------" << endl;

//     Server server;
//     server.Post("/test-post", [](const Request& req, Response& resp){
//         cout << "接收到post请求!" << endl;
//         resp.status = 200;
//     });
//     server.Get("/test-get", [](const Request& req, Response& resp){
//         cout << "接收到get请求!" << endl;
//         resp.status = 200;
//     });
//     server.listen("0.0.0.0", 8080);
//     return 0;
// }